package com.xhwl.centiotdata.handler.visitor.impl;

import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.xhwl.centiotdata.handler.visitor.VisitorIntegrationFactory;
import com.xhwl.centiotdata.handler.visitor.VisitorIntegrationHandler;
import com.xhwl.centiotdata.pojo.constant.DaHuaIccConstant;
import com.xhwl.centiotdata.pojo.dto.dahua.UserDaHuaIccDTO;
import com.xhwl.centiotdata.pojo.dto.dahua.VisitorInfoDaHuaDTO;
import com.xhwl.centiotdata.pojo.dto.visitor.VisitorIntegrationConfigDTO;
import com.xhwl.centiotdata.service.cent.IAccountCentService;
import com.xhwl.centiotdata.service.cent.IAuthAccountCentService;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.service.cent.IVisitorCentService;
import com.xhwl.centiotdata.suppliersystem.dahua.GeneralDaHuaHandler;
import com.xhwl.centiotdata.suppliersystem.dahuaIcc.GeneralDaHuaIccHandler;
import com.xhwl.centiotdata.suppliersystem.dahuaIcc.VisitorDaHuaIccHandler;
import com.xhwl.centiotdata.utils.RedisUtils;
import com.xhwl.common.dto.cent.visitor.IntervieweeCreateDTO;
import com.xhwl.common.dto.cent.visitor.VisitorAuthDTO;
import com.xhwl.common.dto.cent.visitor.VisitorInfoDTO;
import com.xhwl.common.dto.cent.visitor.VisitorOpenDTO;
import com.xhwl.common.enums.CategoryEnum;
import com.xhwl.common.enums.CodeEnum;
import com.xhwl.common.enums.ProductEnum;
import com.xhwl.common.enums.pedestrian.PassMediumEnum;
import com.xhwl.common.enums.visitor.VisitorStatusEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.auth.AuthAccountMapping;
import com.xhwl.common.pojo.cent.device.DeviceProjSupplierCategory;
import com.xhwl.common.pojo.cent.sdata.Account;
import com.xhwl.common.pojo.cent.visitor.Follower;
import com.xhwl.common.query.cent.device.ProductAccessQuery;
import com.xhwl.common.query.cent.sdata.AccountQuery;
import com.xhwl.common.utils.ValidatorUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: yanyixiong
 * @Description:大华ICC 访客对接
 * @Date: create in 9:28 2022/3/4
 */
@Slf4j
@Service
public class VisitorIntegrationDaHuaIccHandler extends VisitorIntegrationHandler {
    @Autowired
    VisitorDaHuaIccHandler visitorDaHuaIccHandler;
    @Autowired
    IAccountCentService accountCentService;
    @Autowired
    IAuthAccountCentService authAccountCentService;
    @Autowired
    GeneralDaHuaIccHandler generalDaHuaIccHandler;
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    IVisitorCentService iVisitorCentService;
    @Autowired
    IDeviceCentService deviceCentService;

    @Override
    public void afterPropertiesSet() throws Exception {
        VisitorIntegrationFactory.register(ProductEnum.DAHUA_ICC.getId(),this);
    }

    public AuthAccountMapping createUser(VisitorIntegrationConfigDTO configDTO, IntervieweeCreateDTO intervieweeCreateDTO) {
        Account account = intervieweeCreateDTO.getAccount();
        AuthAccountMapping authAccountMapping = visitorDaHuaIccHandler.queryUser(account, configDTO);
        if(Objects.nonNull(authAccountMapping)){
            return authAccountMapping;
        }
        String paperNumber = intervieweeCreateDTO.getIdentityNum();
        Date birthday = new Date();
        if(!StringUtils.isEmpty(paperNumber)) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            try {
                // 注意格式需要与上面一致，不然会出现异常
                birthday = sdf.parse(IdcardUtil.getBirth(paperNumber));
            } catch (java.text.ParseException e) {
                e.printStackTrace();
            }
        }

        UserDaHuaIccDTO userDaHuaDTO = UserDaHuaIccDTO.builder().birthday(birthday)
                .code(GeneralDaHuaHandler.generateOpenCode(account.getId(),configDTO.getProjectId()))
                .departmentId(DaHuaIccConstant.DEFAULT_DEPARTMENT_ID)
                .name(account.getName())
                .paperNumber(paperNumber)
                .paperType(DaHuaIccConstant.DEFAULT_PAPER_TYPE)
                .paperAddress(DaHuaIccConstant.DEFAULT_ADDRESS)
                .phone(account.getPhone())
                .service(DaHuaIccConstant.DEFAULT_SERVICE)
                .sex(account.getSex() == null ? 0 : account.getSex().intValue()).build();
        return visitorDaHuaIccHandler.createUser(configDTO, userDaHuaDTO);
    }

    /**
     * 预约授权
     * @param configDTO
     * @param authDTO
     * @return
     */
    @Override
    public ResultJson createVisitorAuth(VisitorIntegrationConfigDTO configDTO, VisitorAuthDTO authDTO) {
        log.info("VisitorAuthDTO:{}", JSONObject.toJSONString(authDTO));
        AuthAccountMapping accountMapping = authAccountCentService.query(configDTO.getProjectId(), authDTO.getIntervieweeId(), configDTO.getProductId());

        String idCardType = "其他";
        if(accountMapping != null) {
            //  处理随访人员信息
            List<Follower> followerList = authDTO.getFollowerList();
            List<VisitorInfoDaHuaDTO.FollowVisitor> followVisitors = new ArrayList<>();
            if(!CollectionUtils.isEmpty(followerList)){
                followerList.forEach(follower -> {
                    VisitorInfoDaHuaDTO.FollowVisitor followVisitor = new VisitorInfoDaHuaDTO.FollowVisitor();
                    followVisitor.setV_name(follower.getName());
                    followVisitor.setV_phone(follower.getPhone());
                    followVisitor.setV_certificateNumber(follower.getPhone());
                    if (!StringUtils.isEmpty(follower.getIdentityCard()) && ValidatorUtil.isIDCard(follower.getIdentityCard())){
                        followVisitor.setV_certificateType("身份证");
                        followVisitor.setV_certificateNumber(follower.getIdentityCard());
                    }
                    if(!StringUtils.isEmpty(follower.getFaceUrl())){
                        followVisitor.setFaceFile(getBaseByUrl(follower.getFaceUrl()));
                    }
                    followVisitors.add(followVisitor);
                });
            }
            // 处理访客信息
            String idCard = authDTO.getPhone();
            if (!StringUtils.isEmpty(authDTO.getIdentityCard()) && ValidatorUtil.isIDCard(authDTO.getIdentityCard())){
                idCardType = "身份证";
                idCard = authDTO.getIdentityCard();
            }
            ProductAccessQuery productAccessQuery = new ProductAccessQuery();
            productAccessQuery.setProjectId(authDTO.getProjectId());
            productAccessQuery.setCategoryId(CategoryEnum.VISITOR_SYSTEM.getId());
            List<DeviceProjSupplierCategory> list = deviceCentService.listProductAccess(null,productAccessQuery);
            JSONObject properties = list.get(0).getProperties();
            log.warn("properties{}",properties);
            VisitorInfoDaHuaDTO visitorInfoDaHuaDTO = VisitorInfoDaHuaDTO.builder()
                    .isv_id(Long.valueOf(accountMapping.getOpenId()))
                    .v_name(authDTO.getName())
                    .v_phone(authDTO.getPhone())
                    .v_certificateType(idCardType)
                    .v_certificateNumber(idCard)
                    .v_dw("访客单位")
                    .v_personSum(1 + (authDTO.getFollowerList() == null ? 0 : authDTO.getFollowerList().size()))
                    .v_reason(authDTO.getSubjectMatter())
                    .v_timeStr(authDTO.getAuthStartTime())
                    .v_lvTimeStr(authDTO.getAuthEndTime())
                    .visitorType(DaHuaIccConstant.VISITOR_TYPE)
                    .areaIdList(Arrays.asList(properties.getString("areaIdList")))
                    .userId(DaHuaIccConstant.USER_ID)
                    .secondVisitorType(DaHuaIccConstant.SECOND_VISITOR_TYPE)
                    .followVisitors(followVisitors)
                    .build();
            if(!StringUtils.isEmpty(authDTO.getFaceUrl())){
                visitorInfoDaHuaDTO.setFaceFile(getBaseByUrl(authDTO.getFaceUrl()));
                log.info("FaceFile:{}",visitorInfoDaHuaDTO.getFaceFile().length());
            }
            List<Integer> passWayList = authDTO.getPassWayList();
            if(CollectionUtils.isNotEmpty(passWayList) && passWayList.contains(PassMediumEnum.FACE.getId())){
                VisitorOpenDTO visitorOpenDTO = visitorDaHuaIccHandler.createVisitorAuth(configDTO, visitorInfoDaHuaDTO);
                visitorOpenDTO.setId(authDTO.getId());
                long before = System.currentTimeMillis();
                iVisitorCentService.updateOpenIdById(visitorOpenDTO);
                long after = System.currentTimeMillis();
                log.warn("修改openIdFeign接口执行时间为{}",after-before);
                return ResultJson.success(visitorOpenDTO.getQrCode());
            }else{
                return ResultJson.success();
            }
        }
        else{
            return ResultJson.fail(CodeEnum.THIRD_PARTY_REQUEST_EXCEPTION.getCode(),"第三方同步权限失败");
        }
    }

    @Override
    public ResultJson getVisitorInfoByIdCard(VisitorIntegrationConfigDTO configDTO, VisitorAuthDTO dto) {
        // 处理访客信息
        String idCard = dto.getPhone();
        if (!StringUtils.isEmpty(dto.getIdentityCard()) && ValidatorUtil.isIDCard(dto.getIdentityCard())){
            idCard = dto.getIdentityCard();
        }
        VisitorInfoDaHuaDTO infoDTO = VisitorInfoDaHuaDTO.builder()
                .v_certificateNumber(idCard)
                .build();
        JSONObject visitorInfo = visitorDaHuaIccHandler.getVisitorInfoByIdCard(configDTO, infoDTO);
        return ResultJson.success(visitorInfo);
    }

    @Override
    public VisitorInfoDTO getVisitorInfoByAppointmentCode(VisitorIntegrationConfigDTO configDTO, String appointmentCode) {
        JSONObject json = visitorDaHuaIccHandler.getVisitorInfoByAppointmentCode(configDTO, appointmentCode);
        if (null == json){
            return null;
        }
        log.info("获取的预约信息{}",json);
        VisitorInfoDTO visitorInfoDTO = new VisitorInfoDTO();
        visitorInfoDTO.setAppointRecordId(json.getString("appointmentCode"));
        visitorInfoDTO.setQrCode(json.getString("v_barCode"));
        visitorInfoDTO.setName(json.getString("isv_name"));
        visitorInfoDTO.setIdentityCard(json.getString("v_certificateNumber"));
        Integer status = json.getInteger("status");
        if (status.equals(DaHuaIccConstant.ARRIVE)) {
            visitorInfoDTO.setStatus(VisitorStatusEnum.ARRIVED);
        }
        if (status.equals(DaHuaIccConstant.LEAVE)) {
            visitorInfoDTO.setStatus(VisitorStatusEnum.LEAVE);
        }
        return visitorInfoDTO;
    }

    @Override
    public ResultJson getOpenDeviceInfo(VisitorIntegrationConfigDTO configDTO, VisitorAuthDTO dto){
        // 获取大华第三方门禁配置信息
        Map<String,List<String>> areaInfoMap = visitorDaHuaIccHandler.getVisitorAreaInfo(configDTO);
        log.warn("获取的areaInfoMap{}",areaInfoMap);
        // 获取平台访客集成配置
        ProductAccessQuery productAccessQuery = new ProductAccessQuery();
        productAccessQuery.setProjectId(configDTO.getProjectId());
        productAccessQuery.setCategoryId(CategoryEnum.VISITOR_SYSTEM.getId());
        List<DeviceProjSupplierCategory> deviceConfigList = deviceCentService.listProductAccess(null, productAccessQuery);
        deviceConfigList = deviceConfigList.stream().filter(item -> item.getProductId().equals(configDTO.getProductId())).collect(Collectors.toList());
        JSONObject properties = deviceConfigList.get(0).getProperties();
        log.warn("获取的properties{}",properties);
        List<String> areaIds = Arrays.asList(properties.getString("areaIdList").split(","));
        List<String> openDeviceName = new ArrayList<>();
        areaIds.forEach(areaId -> {
            if (CollectionUtils.isNotEmpty(areaInfoMap.get(areaId))){
                openDeviceName.addAll(areaInfoMap.get(areaId));
            }
        });
        return ResultJson.success(openDeviceName);
    }
    @Override
    public VisitorInfoDTO getVisitorAccessRecord(VisitorIntegrationConfigDTO integrationConfigDTO, VisitorAuthDTO dto){
        return visitorDaHuaIccHandler.getVisitorAccessRecord(integrationConfigDTO,dto);
    }

    @Override
    public ResultJson removeVisitorAuth(VisitorIntegrationConfigDTO configDTO, VisitorInfoDTO infoDTO) {
        return visitorDaHuaIccHandler.deleteVisitorAuth(configDTO,infoDTO);
    }

    @Override
    public ResultJson getQrCode(VisitorIntegrationConfigDTO configDTO, VisitorAuthDTO visitorAuthDTO) {
        AuthAccountMapping openAccount = this.getOpenAccount(configDTO, visitorAuthDTO);
        visitorAuthDTO.setIntervieweeOpenCode(openAccount.getOpenCode());
        return visitorDaHuaIccHandler.getQrCode(configDTO,visitorAuthDTO);
    }

    private AuthAccountMapping getOpenAccount(VisitorIntegrationConfigDTO configDTO, VisitorAuthDTO visitorAuthDTO){
        AuthAccountMapping authAccountMapping = authAccountCentService.query(visitorAuthDTO.getProjectId(),visitorAuthDTO.getIntervieweeId(), visitorAuthDTO.getProductId());
        if (Objects.isNull(authAccountMapping)|| StringUtils.isEmpty(authAccountMapping.getOpenId())) {
            IntervieweeCreateDTO intervieweeCreateDTO = handleCreateUserDTO(visitorAuthDTO);
            authAccountMapping = this.createUser(configDTO, intervieweeCreateDTO);
            if(Objects.nonNull(authAccountMapping)){
                visitorAuthDTO.setIntervieweeOpenId(authAccountMapping.getOpenId());
                visitorAuthDTO.setIntervieweeOpenCode(authAccountMapping.getOpenCode());
            }
        }
        return authAccountMapping;
    }

    private IntervieweeCreateDTO handleCreateUserDTO(VisitorAuthDTO visitorAuthDTO){
        AccountQuery accountQuery = new AccountQuery();
        Integer intervieweeId = visitorAuthDTO.getIntervieweeId();
        accountQuery.setId(intervieweeId);
        IntervieweeCreateDTO intervieweeCreateDTO = new IntervieweeCreateDTO();
        Account account = accountCentService.getAccount(null,accountQuery);
        intervieweeCreateDTO.setProductId(visitorAuthDTO.getProductId());
        intervieweeCreateDTO.setProjectId(visitorAuthDTO.getProjectId());
        //因为主数据没有身份证 随便生成了 @TODO 从企业通讯录拿
        String identityNum = "43252419950625"+String.format("%04d", intervieweeId);
        intervieweeCreateDTO.setIdentityNum(identityNum);
        intervieweeCreateDTO.setAccount(account);
        return intervieweeCreateDTO;
    }

    public static String getBaseByUrl(String url){
        byte[] bytes = HttpRequest.get(url).execute().bodyBytes();
        String encode = Base64Encoder.encode(bytes);
        return "data:image/jpeg;base64,"+encode;
    }

}
